package semafori;

import java.util.*;

public class SemaforoContatore implements Semaforo {
	private int permessi, daSvegliare = 0;
	private List<Thread> listaDiAttesa = new LinkedList<Thread>();

	public SemaforoContatore(int permessi) {
		if (permessi < 0)
			throw new IllegalArgumentException("Permessi negativi!");
		this.permessi = permessi;
	}

	public synchronized void P() {
		if (permessi == 0) {
			listaDiAttesa.add(Thread.currentThread());
			while (true) {
				try {
					wait();
				} catch (InterruptedException e) {
				}
				if (daSvegliare > 0
						&& listaDiAttesa.get(0) == Thread.currentThread()) {
					daSvegliare--;
					if (daSvegliare > 0)
						notifyAll();
					break;
				}
			}
			listaDiAttesa.remove(0);
		} else
			permessi--;
	}// P

	public synchronized void V() {
		if (listaDiAttesa.size() == 0 || listaDiAttesa.size() == daSvegliare)
			permessi++;
		else {
			daSvegliare++;
			notifyAll();
		}
	}// V
}// SemaforoContatore

